package com.ansion.baseui.base;

import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;

import androidx.annotation.Nullable;

import com.ansion.basetool.observer.BreakNotifyAction;
import com.ansion.basetool.observer.NotifyAction;
import com.ansion.basetool.observer.ObjectManager;

/**
 * @author zhaoyuntao
 * date 2021/6/28
 */
@SuppressWarnings("rawtypes")
public abstract class TVPBaseActivity<P extends TBasePresenter> extends TBaseActivity implements TVPBaseView<P, TVPActivityUIProxy<? extends TBaseActivity, ? extends P>> {

    private P presenter;
    private final ObjectManager<TVPActivityUIProxy<? extends TBaseActivity, ? extends P>> manager = new ObjectManager<>(false);

    @Override
    final protected void initView_base(@Nullable Bundle savedInstanceState) {
        onAddUIProxy();
        initView(savedInstanceState);
        manager.notifyObjects(uiProxy -> {
            uiProxy.initView(savedInstanceState);
        });
    }

    @SuppressWarnings("unchecked")
    @Override
    final protected void initData_base(Bundle savedInstanceState) {
        presenter = createPresenter();
        presenter.onAttachedView(TVPBaseActivity.this);
        initData(savedInstanceState);
        manager.notifyObjects(uiProxy -> {
            uiProxy.initData(savedInstanceState);
        });
    }

    public void onAddUIProxy() {
    }

    @Override
    final public void addUIProxy(TVPActivityUIProxy<? extends TBaseActivity, ? extends P> uiProxy) {
        manager.addObject(uiProxy);
    }

    final public <UIProxy extends TVPActivityUIProxy<? extends TVPBaseActivity, ? extends P>> UIProxy getUIProxy(Class<UIProxy> clazz) {
        UIProxy t = manager.pickObject(clazz);
        if (t == null) {
            throw new RuntimeException("Have you registered this UIProxy[ " + clazz.getSimpleName() + " ]into your activity ?");
        }
        return t;
    }

    @Override
    final public P getPresenter() {
        if (presenter == null) {
            throw new RuntimeException("Please don't use this method in initView()!");
        }
        return presenter;
    }

    @Override
    final public void onClick(View v) {
        if (manager.notifyObjects(uiProxy -> {
            return uiProxy.onClickView(v);
        })) {
            return;
        }
        onClickView(v);
    }

    protected void onClickView(View v) {
    }

    /**
     * When press back key.
     *
     * @return true means consume this click
     */
    @Override
    final public boolean onPressBack() {
        if (manager.notifyObjects((BreakNotifyAction<TVPActivityUIProxy<? extends TBaseActivity, ? extends P>>) TVPActivityUIProxy::onPressedBack)) {
            return true;
        }
        return onPressedBack();
    }

    /**
     * When press back key.
     *
     * @return true means consume this click
     */
    protected boolean onPressedBack() {
        return false;
    }

    @Override
    final protected boolean onKeyPressedDownBase(int keyCode, KeyEvent event) {
        if (manager.notifyObjects(uiProxy -> {
            return uiProxy.onKeyPressedDown(keyCode, event);
        })) {
            return true;
        }
        return onKeyPressedDown(keyCode, event);
    }

    private boolean onKeyPressedDown(int keyCode, KeyEvent event) {
        return false;
    }

    @Override
    final protected void _onStartActivity() {
        manager.notifyObjects((NotifyAction<TVPActivityUIProxy<? extends TBaseActivity, ? extends P>>) TVPActivityUIProxy::onStartActivity);
    }

    @Override
    final protected void _onRestartActivity() {
        manager.notifyObjects((NotifyAction<TVPActivityUIProxy<? extends TBaseActivity, ? extends P>>) TVPActivityUIProxy::onRestartActivity);
    }

    @Override
    final protected void _onResumeActivity() {
        manager.notifyObjects((NotifyAction<TVPActivityUIProxy<? extends TBaseActivity, ? extends P>>) TVPActivityUIProxy::onResumeActivity);
    }

    @Override
    final protected void _onPauseActivity() {
        manager.notifyObjects((NotifyAction<TVPActivityUIProxy<? extends TBaseActivity, ? extends P>>) TVPActivityUIProxy::onPauseActivity);
    }

    @Override
    final protected void _onStopActivity() {
        manager.notifyObjects((NotifyAction<TVPActivityUIProxy<? extends TBaseActivity, ? extends P>>) TVPActivityUIProxy::onStopActivity);
    }

    @Override
    final protected void _onDestroyActivity() {
        manager.notifyObjects((NotifyAction<TVPActivityUIProxy<? extends TBaseActivity, ? extends P>>) TVPActivityUIProxy::onDestroyActivity);
        presenter.onDetachedView();
    }

    @Override
    final protected boolean onFinish() {
        manager.notifyObjects((NotifyAction<TVPActivityUIProxy<? extends TBaseActivity, ? extends P>>) TVPActivityUIProxy::onFinishActivity);
        return onFinishActivity();
    }

    /**
     * @return if true would call super.finish()
     */
    protected boolean onFinishActivity() {
        return true;
    }
}
